package com.itshare.video.common.aop.xss.support;

import com.itshare.video.common.aop.AopPropertyUtils;
import com.itshare.video.common.aop.AopUtils;
import com.itshare.video.common.aop.xss.annontation.CleanXSS;
import com.itshare.video.common.util.XssUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;

/**
 * 有两套实现，这一套实现了对 嵌套 JSON 移除 js
 *
 * @Author lyr
 * @create 2020/11/3 23:02
 */
@Aspect
@Component
@Slf4j
@Lazy
public class XssAspect {
    @Pointcut("@annotation(com.itshare.video.common.aop.xss.annontation.CleanXSS)")
    public void xssAOP() {
        // log.info("args-> {}", Arrays.toString(pjp.getArgs()));
    }

    @Around("xssAOP()")
    public Object aroundForExpireCache(ProceedingJoinPoint joinPoint) throws Throwable {
        // CleanXSS cleanXSS = AopUtils.getAopMethod(joinPoint).getAnnotation(CleanXSS.class);
        // // String key = SpelUtil.generateKeyBySpEL(redisCacheExpire.spel(),joinPoint);
        // // expireCache(redisCacheExpire,key);
        // // System.out.println("调用了 xss 切面");

        Object[] args = joinPoint.getArgs();
        // Annotation[][] paramAnnontations = AopUtils.getAopMethod(joinPoint).getParameterAnnotations();
        Parameter[] parameters = AopUtils.getAopMethod(joinPoint).getParameters();
        for (int i=0;i<parameters.length;++i) {
            Object paramValue = args[i];
            Parameter parameter = parameters[i];
            if (parameter.isAnnotationPresent(CleanXSS.class) && (paramValue instanceof String)) {
                CleanXSS strategy = parameter.getAnnotation(CleanXSS.class);
                //去掉 尖角
                String txtValue= XssUtil.escapeJSAndHtml(strategy,(String) paramValue);
                args[i] = txtValue;
            }
            if (!AopPropertyUtils.isJavaApi(paramValue.getClass())) {
                //是自定义对象
                removeXSS(paramValue);
            }
        }

        // for (int i = 0; i < args.length; ++i) {
        //     //校验
        //     Class clazz = args[i].getClass();
        //     if (clazz.isPrimitive() || Number.class.isAssignableFrom(clazz)) {
        //         //如果是元数据，直接跳过
        //         continue;
        //     } else {
        //         if(AopPropertyUtils.isJavaApi(clazz)) {
        //             //如果是java的属性
        //             continue;
        //         }
        //         //parameter at i
        //         Object obj = args[i];
        //         //parameter_i_property
        //         for (Field field : obj.getClass().getDeclaredFields()) {
        //             Class fieldClazz = field.getType();
        //
        //             if (!field.isAccessible()) {
        //                 field.setAccessible(true);
        //             }
        //             //先设置可以访问
        //             if (String.class.isAssignableFrom(fieldClazz) && field.isAnnotationPresent(CleanXSS.class)) {
        //                 //是 string
        //                 String value = (String) field.get(obj);
        //                 if (value != null) {
        //                     CleanXSS cleanXSS1 =  field.getAnnotation(CleanXSS.class);
        //                     String txtValue = XssUtil.escapeJSAndHtml(cleanXSS1,value);
        //                     // if(cleanXSS1.type()== CleanXSS.type.EscapeALL) {
        //                     //
        //                     //     txtValue = XssUtil.escapeHtml(value);
        //                     // }else{
        //                     //     //先去js ,再转义
        //                     //     txtValue = XssUtil.cleanXSS(value);
        //                     //     // txtValue = XssUtil.escapeHtml(txtValue);
        //                     // }
        //                     // System.out.println(txtValue);
        //                     // System.out.println("出xss");
        //                     //防止xss
        //                     field.set(obj, txtValue);
        //                 }
        //             } else if (!(AopPropertyUtils.isJavaApi(fieldClazz))) {
        //                 // System.out.println("xx");
        //                 //不是简单类型
        //                 // System.out.println("触发递归");
        //                 removeXSS(field.get(obj));
        //
        //                 // });
        //             }
        //         }
        //     }
        // }


        return joinPoint.proceed(args);

    }


    private void removeXSS(Object value) throws IllegalAccessException {
        if (value == null) {
            return;
        }
        Class clazz = value.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            Class fieldClazz = field.getType();
            //如果是 String 类型
            if (String.class.isAssignableFrom(fieldClazz) && fieldClazz.isAnnotationPresent(CleanXSS.class)) {
                //是 string
                String fieldValue = (String) field.get(value);
                if (fieldValue != null) {
                    CleanXSS cleanXSS2 = (CleanXSS) clazz.getAnnotation(CleanXSS.class);
                    String txtValue = XssUtil.escapeJSAndHtml(cleanXSS2,(String)fieldValue);
                    // if(cleanXSS2.type()== CleanXSS.type.EscapeALL) {
                    //     txtValue = XssUtil.escapeHtml((String) field.get(fieldValue));
                    // }else{
                    //     //先去js ,再转义
                    //     txtValue = XssUtil.cleanXSS((String)field.get(fieldValue));
                    //     // txtValue = XssUtil.escapeHtml(txtValue);
                    // }
                    //防止xss
                    field.set(value,  txtValue);
                }
            } else if (!(AopPropertyUtils.isJavaApi(fieldClazz))) {
                //如果不是 java的 api ,那就是自定义的 api
                Object fieldValue = field.get(value);
                if (fieldValue != null) {
                    //递归调用，移除 String 的 xss
                    removeXSS(fieldValue);

                }

                // });
            }
        }
    }
}
